import java.awt.event.ActionEvent;
import java.util.Random;

import javax.swing.JButton;


public class BarbedWire extends RandomEvent {
	
	private JButton cut;
	private JButton jump;
	//private boolean wasJumped, wasCut;
	private Random rand;
	private double height;
	private double thickness;

	/**
	 * Creates a BarbedWire of random height and thickness. 
	 * @param display The panel that the barbed wire will display
	 * to when it is encountered by the player.
	 * @param party The party that will encounter the barbed wire.
	 */
	public BarbedWire(MainCardPanel display, Party party) {
		super(display, party);
		cut = new  JButton("Cut");
		cut.addActionListener(this);
		jump = new JButton("Jump over");
		jump.addActionListener(this);
		displayName = "A barbed wire fence blocks your path";
		//wasJumped = false;
		//wasCut = false;
		rand = new Random();
		height = rand.nextDouble()*3.0+4;
		thickness = rand.nextDouble()*0.4 + 0.3;
		imageFilename = "BarbedWire.jpg";
		dead = false;
	}
	
	@Override
	/**
	 * sets the BarbedWire to dead if it is not fresh.
	 * @see RandomEvent
	 */
	public void decay() {
		super.decay();
		if (dead)
			return;
		if (!fresh)
			dead = true;
	}
	
	
	/**
	 * Returns the buttons linked to jumping and cutting the BarbedWire.
	 * @return A JButton[] of length 2.
	 */
	@Override
	public JButton[] getResponseElements() {
		if (p.hasWireCutters()) {
			JButton[] ret = {cut, jump};
			return ret;
		}
		JButton[] ret = {jump};
		return ret;
		
	}
	
	private void dealWithBarbedWireWrapper(boolean cut)
	{
		RandomEvent misfortune = dealWithBarbedWire(cut);
		if (misfortune != null)
			p.addRandomEvent(misfortune);
	}
	/**
	 * Simulates the Party jumping over or cutting the barbed wire. This method
	 * should never be called with input true if the party does not have wire cutters.
	 * When jumping, damages the first member of the Party to jump lower than the fence.
	 * When cutting, damages the wire cutters.
	 * @param cut True indicates that the party chose to cut the BarbedWire.
	 * 			False indicates that the party chose to jump the BarbedWire.
	 * @return RandomEvent an event that occurs while the Party interacts with the fence.
	 * Returns nulls if no event occurs.
	 */
	public RandomEvent dealWithBarbedWire(boolean cut) {
		if (cut) {
			if (this.cut(p.getWireCutters()))
				return
					new ItemLoss
					    (
					    	display, 
					    	p, 
					    	"Your wire cutters broke.", 
					    	Item.ItemType.wire_cutters
						);
		}
		else 
			for (Member m:p.getTravellers())
				if (this.jumpOver(m) ) {
					return
							new Injury
						      	(
						    	   display, 
						    	   m + " was injured jumping over barbed wire.", 
						    	   m, 
						    	   20,
						    	   p
						        );
				}
		return null;
	}
	
	/**
	 * Simulates the cutting of this BarbedWire.
	 * @param wireCutters The WireCutters that will perform the wire cutting
	 * @return True if the wire cutters broke, false if not.
	 */
	public boolean cut(Item wireCutters) {
		return wireCutters.damage(thickness);
	}
	
	/**
	 * Simulates the given member jumping over the barbed wire.
	 * @param t the Member that jumps over the barbed wire.
	 * @return false if the Member jumped over unharmed, true otherwise.
	 */
	public boolean jumpOver(Member t) {
		return t.jump() <= height;
	}
	
	/**
	 * Determines if the event passed in came from the user choosing to
	 * jump the wire, or if it came from the user choosing to cut the wire,
	 * Then calls the dealWithBarbedWire method passing the user's choice and
	 * a random jump value for the case that the user chose to jump.
	 * @see RandomEvent#actionPerformed(java.awt.event.ActionEvent)
	 */
	@Override
	public void actionPerformed(ActionEvent e) {
		super.actionPerformed(e);
		if (e.getSource()==cut)
			dealWithBarbedWireWrapper(true);
		else if (e.getSource()==jump)
			dealWithBarbedWireWrapper(false);
			
	}
	
	/**
	 * Returns the height of this barbed wire in feet.
	 * @return a double representing height.
	 */
	public double getHeight() {
		return height;
	}
	
	/**
	 * sets the thickness of the BarbedWire.
	 * @param thickness The thickness to set to in inches.
	 */
	public void setThickness(double thickness) {
		this.thickness = thickness;
		
	}

}
